package com.ncr.travel.airline.shared.configuration.checkin;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ncr.travel.airline.shared.configuration.converters.CountryAirportCode.CountryReference;
import com.ncr.travel.airline.shared.configuration.converters.FeatureSettings;
import com.ncr.travel.tas.configuration.model.ConfigurationValue;
import com.ncr.travel.tas.configuration.model.ConfigurationValueTemplate;
import com.ncr.travel.tas.shared.configuration.ConfigurationKey;
import com.ncr.travel.tas.shared.configuration.ConfigurationNodeEnum;
import com.ncr.travel.tas.shared.configuration.ConfigurationProductKey;
import com.ncr.travel.tas.shared.configuration.ConfigurationServiceException;

public class WebCheckInConfigurationImpl extends CommonCheckInConfigurationImpl implements WebCheckInConfiguration {
	private final static Logger logger = LoggerFactory.getLogger(WebCheckInConfigurationImpl.class);

	private SharedCheckInConfiguration sharedConfiguration;

	public SharedCheckInConfiguration getSharedConfiguration() {
		return sharedConfiguration;
	}

	public void setSharedConfiguration(SharedCheckInConfiguration sharedConfiguration) {
		this.sharedConfiguration = sharedConfiguration;
	}

	@Override
	public Set<ConfigurationValue> getConfigurationChildren(CheckInConfiguration node) {
		return sharedConfiguration.getConfigurationChildren(node);
	}

	@Override
	public boolean isFeatureOn(CheckInFeature feature) {
		try {
			switch (feature) {
			case LAP_INFANT:
				return sharedConfiguration.isFeatureOn(feature) &&
						(Boolean) loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.LAP_INFANT).getValue();
			case EMAIL_BOARDING_PASS:
				return 	(Boolean) loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.EMAIL_OPTIONS).findChild("BoardingPass").getValue();
			case EMAIL_TICKET_RECEIPT:
				return 	(Boolean) loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.EMAIL_OPTIONS).findChild("Receipt").getValue();
			case PRINT_BOARDING_PASS:
				return 	(Boolean) loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.PRINT_OPTIONS).findChild("BoardingPass").getValue();
			case PRINT_TICKET_RECEIPT:
				return 	(Boolean) loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.PRINT_OPTIONS).findChild("Receipt").getValue();
			case PROFILE_AUTHENTICATION:
				return (Boolean) loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.PROFILE_AUTHENTICATION).getValue();
			default:
				return sharedConfiguration.isFeatureOn(feature);
			}
		} catch (ConfigurationServiceException e) {
			logger.error(e.getMessage());
			return false;
		}
		//TODO: handle web-specific feature overrides?
		//return false;
	}

	/**
	 * returns a list of find by option constructs for the web application
	 * @return
	 * @throws ConfigurationServiceException
	 */
	public List<CheckInFeature> getFindByOptions() {
		List<CheckInFeature> availableFindByOptions = new ArrayList<CheckInFeature>();

		if (sharedConfiguration.isFeatureOn(CheckInFeature.FIND_RESERVATION_BY_CONFIRMATION_NUMBER)) {
			availableFindByOptions.add(CheckInFeature.FIND_RESERVATION_BY_CONFIRMATION_NUMBER);
		}
		if (sharedConfiguration.isFeatureOn(CheckInFeature.FIND_RESERVATION_BY_TICKET_NUMBER)) {
			availableFindByOptions.add(CheckInFeature.FIND_RESERVATION_BY_TICKET_NUMBER);
		}
		if (sharedConfiguration.isFeatureOn(CheckInFeature.FIND_RESERVATION_BY_LOYALTY_PROGRAM)) {
			availableFindByOptions.add(CheckInFeature.FIND_RESERVATION_BY_LOYALTY_PROGRAM);
		}
		if (sharedConfiguration.isFeatureOn(CheckInFeature.FIND_RESERVATION_BY_CARD)) {
			availableFindByOptions.add(CheckInFeature.FIND_RESERVATION_BY_CARD);
		}

		return availableFindByOptions;
	}
	
	public ConfigurationValueTemplate getTemplateForOptionslField(
			CheckInFeature findByOption, FindByOptionalField field) {
		return sharedConfiguration.getTemplateForOptionslField(findByOption, field);
	}
	
	public List<FindByOptionalField> availableOptionalFindByFields (CheckInFeature findByOption)
	{
		List<FindByOptionalField> optionalFields = new ArrayList<FindByOptionalField>();
		return optionalFields;
	}
	

	/**
	 * attempts to communicate with configuration subsystem to retrieve arrival cities
	 * @param sessionKey
	 * @return
	 * @throws ConfigurationServiceException
	 */
	public List<String> getArrivalAirports() {
		//TODO: Move this into Shared???

		List<String> availableFindByOptions = new ArrayList<String>();

		// get the root node where the find by options are located
		ConfigurationValue arrivalOptionsParent = loadValueFromService(ConfigurationNodeEnum.GLOBAL, ConfigurationProductKey.SHARED, ConfigurationKey.ARRIVAL_CITIES);

		// the find by options are the children of this node
		Set<ConfigurationValue> arrivalOptions = arrivalOptionsParent.getChildValues();

		for (ConfigurationValue value : arrivalOptions) {

			if (((Boolean) value.getValue()) == true) {
				availableFindByOptions.add((String) value.getKeyName());
			}
		}

		//sort by natural order for now (alphabetically)
		Collections.sort(availableFindByOptions);

		return availableFindByOptions;

	}

	/**
	 * attempts to communicate with configuration subsystem to get the departure cities
	 * @param sessionKey
	 * @return
	 * @throws ConfigurationServiceException
	 */
	public List<String> getDepartureAirports() {
		//TODO: Move this into Shared???

		List<String> availableFindByOptions = new ArrayList<String>();

		// get the root node where the find by options are located
        ConfigurationValue departureOptionsParent = loadValueFromService(ConfigurationNodeEnum.GLOBAL, ConfigurationProductKey.SHARED, ConfigurationKey.DEPARTURE_CITIES);

		// the find by options are the children of this node
		Set<ConfigurationValue> departureOptions = departureOptionsParent.getChildValues();

		for (ConfigurationValue value : departureOptions) {

			if (((Boolean) value.getValue()) == true) {
				availableFindByOptions.add((String) value.getKeyName());
			}
		}

		//sort by natural order for now (alphabetically)
		Collections.sort(availableFindByOptions);

		return availableFindByOptions;

	}

	@Override
	public ConfigurationValueTemplate getTemplateForField(CheckInField field) {
		return sharedConfiguration.getTemplateForField(field);
	}

	@Override
	public String getHostAirlineCode() {
		return sharedConfiguration.getHostAirlineCode();
	}

	@Override
	public String getHostAirlineName() {
		return sharedConfiguration.getHostAirlineName();
	}

	@Override
	public String getHostAirlineLoyaltyProgramName() {
		return sharedConfiguration.getHostAirlineLoyaltyProgramName();
	}

	@Override
	public int getMinimumMinutesBeforeDeparture() {
		ConfigurationValue value = loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.CHECK_IN_TIMES)
									.findChild("MinimumMinutesBeforeDeparture");
		return (Integer) value.getValue();
	}

	@Override
	public int getMaximumMinutesBeforeDeparture() {
		ConfigurationValue value = loadValueFromService(ConfigurationNodeEnum.WEB, ConfigurationProductKey.WEB_CHECKIN, ConfigurationKey.CHECK_IN_TIMES)
									.findChild("MaximumMinutesBeforeDeparture");
		return (Integer) value.getValue();
	}

	@Override
	public boolean isFindByOptionalFieldOn(CheckInFeature feature,
			FindByOptionalField field) {
		return sharedConfiguration.isFindByOptionalFieldOn(feature, field);
	}

    /**
     * Required implementation.
     *
     * @see CommonCheckInConfiguration#getAvailableCountries()
     */
    @Override
    public Collection<CountryReference> getAvailableCountries() {
        return this.sharedConfiguration.getAvailableCountries();
    }

    /**
     * Required implementation.
     *
     * @see CommonCheckInConfiguration#getCountrySubdivisions(String)
     */
    @Override
    public List<ConfiguredPair> getCountrySubdivisions(String countryCode) {
        return this.sharedConfiguration.getCountrySubdivisions(countryCode);
    }

    /**
     * Required implementation.
     *
     * @see CommonCheckInConfiguration#getParentCountry(String)
     */
    @Override
    public String getParentCountry(String countryCode) {
        return this.sharedConfiguration.getParentCountry(countryCode);
    }

    /**
	 * TGAIR-1409
	 * @return if the login dialog is turned ON/OFF
	 */
	@Override
	public boolean isProfileAuthenticationEnabled() {
		return this.isFeatureOn(CheckInFeature.PROFILE_AUTHENTICATION);
	}

	@Override
	public FeatureSettings getSettingsForFeature(CheckInFeature feature) {
		return this.sharedConfiguration.getSettingsForFeature(feature);
	}

}
